

class Rogaru::Tilemap::Layer
	def initialize(map, wide, high, tilehigh= 40, tilewide = 40 ) 
		@map   = map
		@layer = []
		@layer_save = []
		@high = high
		@wide = wide
		for index in (0...@high)
			@layer[index] = []
			@layer_save[index] = []
			for jdex in (0...@wide)
				@layer[index].push(nil)
				@layer_save[index].push(-1)
			end	
		end
		@tilehigh = tilehigh
		@tilewide = tilewide	
		@realhigh = @tilehigh * @high
		@realwide = @tilewide * @wide
		@x = 0
		@y = 0
		@vx = 0
		@vy = 0
	end
	
	def set_tiles(tilearray) 
		@tiles = tilearray
	end

	def add_tile(tile) 
		return @map.add_tile(tile)
	end

	def set(x, y, tile_id)
		raise "Index #{x} #{y} #{tile_id} not valid." if (x < 0) or (y<0) or ( x >= @wide) or (y >= @high)
		if tile_id.nil? or tile_id < 0 then 
			real_tile_id 	= -1
			real_tile 		= nil
		else
			real_tile 		= @map.get_tile(tile_id)
			real_tile_id 	= tile_id
		end
		@layer[y][x] 		= real_tile 
		@layer_save[y][x]  	= real_tile_id
	end
	
	def get(x, y) 
		gx = x; gy = y
		gy = @high if gy > @high
		gx = @wide if gx > @wide
		gy = 0 if gy < 0 
		gx = 0 if gx < 0
		return @layer_save[gy][gx]
	end

	def draw(screen, x, y)
		txstart     = ( x / @tilewide )
		tystart     = ( y / @tilehigh )
		xtilestop   = (screen.w / @tilewide) + 1
		ytilestop   = (screen.h / @tilehigh) + 1
		txstop      = xtilestop + txstart
		tystop      = ytilestop + tystart
		drawx       = 0
		drawy       = 0
		row         = nil
		aidimage    = nil
		nilcount    = 0
		return if (txstart >= @wide or tystart >= @high) 
		txstart = 0    if (txstart < 0) 
		tystart = 0    if (tystart < 0)
		txstop  = @wide if (txstop > @wide) 
		tystop  = @high if (tystop > @high) 
		drawy   = -y + ( (tystart-1) * @tilehigh )
		for tydex in (tystart...tystop) do 
			drawy   += @tilehigh;
			drawx   = -x + ( (txstart-1) * @tilewide )
			row     = @layer[tydex]
			for txdex in (txstart...txstop) do
				drawx   += @tilewide				
				aidtile  = row[txdex]
				unless aidtile.nil? then
					aidimage    = aidtile.get
					aidimage.blit(screen, [drawx, drawy] )
				end
			end
        end
	end

	def draw_effects(screen, x, y)
		txstart     = ( x / @tilewide )
		tystart     = ( y / @tilehigh )
		xtilestop   = (screen.w / @tilewide) + 1
		ytilestop   = (screen.h / @tilehigh) + 1
		txstop      = xtilestop + txstart
		tystop      = ytilestop + tystart
		drawx       = 0
		drawy       = 0
		row         = nil
		aidimage    = nil
		nilcount    = 0
		return if (txstart >= @wide or tystart >= @high) 
		txstart = 0    if (txstart < 0) 
		tystart = 0    if (tystart < 0)
		txstop  = @wide if (txstop > @wide) 
		tystop  = @high if (tystop > @high) 
		drawy   = -y + ( (tystart-1) * @tilehigh )
		for tydex in (tystart...tystop) do 
			drawy   += @tilehigh;
			drawx   = -x + ( (txstart-1) * @tilewide )
			row     = @layer[tydex]
			for txdex in (txstart...txstop) do
				drawx   += @tilewide				
				aidtile  = row[txdex]
				unless aidtile.nil? then
					screen.draw_box_s([drawx, drawy], [drawx+2, drawy+2], [10,10,10]) unless aidtile.walk
					screen.draw_box_s([drawx+4, drawy], [drawx+6, drawy+2], [0,0,255]) if aidtile.swim
					screen.draw_box_s([drawx, drawy+4], [drawx+2, drawy+6], [255,0,0]) if aidtile.pain
					screen.draw_box_s([drawx+8, drawy], [drawx+10, drawy+2], [0,255,255]) unless aidtile.jump
					screen.draw_box_s([drawx+12, drawy], [drawx+14, drawy+2], [255,255,0]) if aidtile.ledge
					screen.draw_box_s([drawx+16, drawy], [drawx+18, drawy+2], [255,255,255]) if aidtile.up
					screen.draw_box_s([drawx+16, drawy+16], [drawx+18, drawy+18], [255,255,255]) if aidtile.down
				end
			end
        end
	end

	def w
		return @realwide
	end

	def h
		return @realhigh
	end
	
	def tw
		return @wide
	end

	def th
		return @high
	end

	def to_xml() 
		layer = REXML::Element.new 'layer'
		sizehash = {'wide' => @wide.to_s, 
					'high' => @high.to_s,
					'tilewide' => @tilewide.to_s, 
					'tilehigh' => @tilehigh.to_s }
					
		layer.add_attributes(sizehash)
		rows = layer.add_element 'rows'
		for y in (0...@high) do
			row = rows.add_element('row')
			row.add_attribute('y', y.to_s) 
			row.text = @layer_save[y].join(' ');			
		end
		return layer
	end
	
	def self.new_from_xml(xml_layer, map)
		mw    = xml_layer.attributes['wide'].to_i
		mh    = xml_layer.attributes['high'].to_i
		tw    = xml_layer.attributes['tilewide'].to_i
		th 	  = xml_layer.attributes['tilehigh'].to_i
		layer = Tilemap::Layer.new(map, mw, mh, tw, th)
		xml_layer.elements.each('rows/row') do | xml_row |
			y   = xml_row.attributes['y'].to_i
			row = xml_row.text.tr("\n\t\r,;", "     ").strip.split(" ").map { |v| v.to_i  }
			# parse the row, translate all seps to spaces, strip the edges, and split on space
			# and finally transfor into an array of integers.
			stop = row.size
			for x in (0...stop) do
				layer.set(x, y, row[x])
			end
		end
		return layer
	end
		
	def screen_to_tile_x(top_x, screen_x)
		return ((top_x + screen_x) / @tilewide).floor
	end 
	
	def screen_to_tile_y(top_y, screen_y)
		return ((top_y + screen_y) / @tilehigh).floor
	end 

	def tile_to_screen_x(top_x, tile_x)
		return   (tile_x * @tilewide) - top_x
	end 
	
	def tile_to_screen_y(top_y, tile_y)
		return   (tile_y * @tilehigh) - top_y
	end 

	

end

